<template>
  <div class="grid-content" style="height: 100%;border: 2px solid green;position: relative;top: 10px;overflow: scroll">
    <div style="width: 100%;margin: auto;position: relative; top: 10px;">
      <el-input placeholder="搜索目录名" v-model="filterText">
        <el-button slot="append" icon="el-icon-search"></el-button>
      </el-input>
    </div>
    <div style="position: relative; top: 20px;">
      <el-tree
        :style="{height: scrollerHeight, overflow:'auto'}"
        class="filter-tree"
        :data="treeData"
        :props="defaultProps"
        :node-key="id"
        :expand-on-click-node="false"
        @node-click="handleNodeClick"
        default-expand-all
        draggable
        highlight-current
        @node-drop="handleDrop"
        :filter-node-method="filterNode"
        ref="tree">
        <span class="custom-tree-node" slot-scope ="{ node, data }"
        @dblclick="() => { data.allowRename = true; }">
          <span class="custom-tree-node-wrapper">
            <span :title="node.label + '(' + data.caseIds.length + ')'" class="custom-tree-node-label" v-if="!data.allowRename && data.caseIds">
              <i :class="data.icon"></i> {{ node.label }}({{data.caseIds.length}})
            </span>
            <el-input
              size="mini"
              ref="inputVal"
              v-if="data.allowRename || data.isEdit"
              :value="data.text"
              v-model.trim="data.text"
              @focus=focus($event,node)
              @input="item => inputFunc(item, data)"
              @blur="saveInputFunc({node, data, $event})"
              @keyup.enter.native="enterBlur"
              v-autoFocus
            ></el-input>
            <span class="operate-btns">
              <DotDropDown v-if="data.id === 'root'" :events="rootMenuEvents" :data="{node,data}"
                           @addSubFolder="addSubFolder"  @renameFolder="renameFolder"
              />
              <DotDropDown v-if="data.id === '-1'" :events="UnclassifiedMenuEvents" :data="{node,data}"
                           @addPeerFolder="addPeerFolder"
              />
              <DotDropDown v-if="data.id !== 'root' && data.id !== '-1'" :events="dropMenuEvents" :data="{node,data}"
                           @addPeerFolder="addPeerFolder" @addSubFolder="addSubFolder"  @renameFolder="renameFolder"
                           @delFolder="delFolder"
              />
            </span>
          </span>
        </span>
      </el-tree>
    </div>
  </div>
</template>

<script>
import DotDropDown from "@/components/case/caselist/DotDropDown";
import request from "@/utils/axios";
export default {
  name: 'TreeNavigation',
  components:{
    DotDropDown
  },
  props: {
    treeData: {
      type: Array,
      default: () => []
    },
    productLineId: {
      default: '1'
    }
  },
  data(){
    return {
      id: 'id',
      filterText: '',
      currentTree: [],
      expandedKeys: ['root'], //展开树节点,
      whetherEditNodeName: false, // 是否修改节点名称
      defaultProps: {
        children: 'children',
        label: 'text'
      },
      dropMenuEvents: [
        { label: '新建同级', funcName: 'addPeerFolder' },
        { label: '新建子级', funcName: 'addSubFolder' },
        { label: '重命名', funcName: 'renameFolder' },
        { label: '删除', funcName: 'delFolder' }
      ],
      rootMenuEvents: [
        { label: '新建子级', funcName: 'addSubFolder' },
        { label: '重命名', funcName: 'renameFolder' }
      ],
      UnclassifiedMenuEvents: [
        { label: '新建同级', funcName: 'addPeerFolder' }
      ]
    }
  },
  directives: {
    // 自动获取焦点
    autoFocus: {
      inserted: function (el) {
        el.querySelector("input").focus();
      },
    },
  },
  methods: {
    enterBlur(event) {
      event.target.blur()
    },
    focus: function (event) {
      event.currentTarget.select()
    },
    inputFunc(value, data) {
      // 修改
      this.whetherEditNodeName = true;
      // 这里得加判断，如果输入空，就显示之前的值
      if (value === "") {
        this.whetherEditNodeName = false
      } else {
        data.text = value;
      }
    },
    saveInputFunc({node, data, event}) {
      if (data.text === ''){
        if (data.id === '1444')  {
          this.$refs.tree.remove(data)
        } else {
          this.$message({
            type: 'error',
            message: '文件夹名字不能为空，请重新输入！'
          });
        }
      }
      else if (data.allowRename && data.text) {
        this.renameFolder({node, data, event})
      }
      else if (data.isEdit && data.text) {
        this.addDir(data.text, data.parentId)
      }
    },
    handleNodeClick(data,node) {
      this.$emit('chooseDirId', data)
    },
    filterNode(value, data) {
      if (!value) return true
      return data.text.indexOf(value) !== -1
    },
    addNode(key, data ) {
      return data.map(item => {
        const node = {...item};
        if (key === item.id) {
          const newNode = {
            parentId: node.id,
            id: '1444',
            text: '',
            children: [],
            isEdit: true,
            allowRename: false
          };
          return {...item, children: [...item.children, newNode]};
        }
        node.children = this.addNode(key, node.children);
        return node;
      });
    },
    removeNode(node, data) {
      const parent = node.parent;
      const children = parent.data.children || parent.data;
      const index = children.findIndex(d => d.id === data.id);
      children.splice(index, 1);
      // 调删除目录接口
      let url = '/dir/delete'
      request(url, {
        method: 'POST',
        body: {
          delId: data.id,
          parentId: data.parentId,
          productLineId: Number(this.productLineId),
          channel: 1,
        },
      }).then((res = {}) => {
        if (res.code === 200) {
          this.$emit('getDirList')
          this.$message({
            type: 'success',
            message: '成功删除'+ data.text + '目录'
          });
        } else {
          this.$message({
            type: 'error',
            message: res.msg
          });
        }
      });
    },
    handleDrop(draggingNode, dropNode, dropType, event) {
      console.log('draggingNode: , dropNode: , dropType: , event: ' ,draggingNode, dropNode, dropType, event)
      if (draggingNode.data.id === '-1') {
        this.$message({
          type: 'success',
          message: '未分类用例集不可移动!'
        });
      } else if (dropNode.data.id === '-1') {
        this.$message({
          type: 'success',
          message: '未分类用例集下不可有其他文件!'
        });
      } else {
        let toId = dropType !== 'inner'? dropNode.parent.data.id : dropNode.data.id
        let fromId = draggingNode.data.id
        this.moveFolder({
          productLineId: this.$route.params.productLineId,
          fromId,
          toId,
          channel: 1,
        });
      }
    },
    moveFolder: function (params){
      let url = `/dir/move`
      request(url, { method: 'POST', body: params }).then((res = {}) => {
        if (res.code === 200) {
          this.$message({
            type: 'success',
            message: '移动目录成功'
          });
          this.$emit('getDirList')
        } else {
          this.$message({
            type: 'error',
            message: res.msg
          });
        }
      });
    },
    renameFolder({node, data, event}) {
      // data里有节点名称，后端需要就传过去
      console.log('rename data text:', data.text)
      if (this.whetherEditNodeName) {
        // 调用后端修改nodeName的接口
        // 这里加判断是为了避免，双击后没修改nodeName也会调接口的情况
        this.renameDir(node, data)
      }
      data.allowRename = !data.allowRename;
      this.whetherEditNodeName = false
    },
    addPeerFolder: function ({ node, data }) {
      console.log('add peer folder: ', data)
      const newTree = this.addNode(data.parentId, this.treeData);
      this.$emit("update:treeData", newTree)
    },
    addSubFolder: function ({ node, data }) {
      const newTree = this.addNode(data.id, this.treeData);
      this.$emit("update:treeData", newTree)
    },
    addDir: function (value, parentId) {
      let url = '/dir/add'
      request(url, {
        method: 'POST',
        body: {
          parentId: parentId,
          productLineId: Number(this.productLineId),
          text: value,
          channel: 1,
        },
      }).then((res = {}) => {
        if (res.code === 200) {
          this.$emit('getDirList')
          this.$message({
            type: 'success',
            message: '添加目录成功'
          });
        } else {
          this.$message({
            type: 'error',
            message: res.msg
          });
        }
      });
    },
    renameDir: function ( node, data) {
      let url = '/dir/rename'
      request(url, {
        method: 'POST',
        body: {
          id: data.id,
          productLineId: Number(this.productLineId),
          text: data.text,
          channel: 1,
        },
      }).then((res = {}) => {
        if (res.code === 200) {
          this.$emit('getDirList')
          this.$message({
            type: 'success',
            message: '重命名成功'
          });
        } else {
          this.$message({
            type: 'error',
            message: res.msg
          });
        }
      });
    },
    delFolder: function ({ node, data }) {
      const h = this.$createElement;
      let inputText = '确认删除'
      if (data.caseIds.length > 0) {
        this.$prompt( '正在删除 '+ data.text +' 目录，目录包含 ' + data.caseIds.length+ '条用例, ' + '请输入：' + inputText.bold(), '确认删除目录？', {
          dangerouslyUseHTMLString: true,
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning',
          inputPlaceholder: '确认删除',
          inputPattern: /确认删除/,
          inputErrorMessage: '输入有误',
          center: true
        }).then (() => {
          this.removeNode(node, data)   // 删除节点
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        })
      } else {                        // 目录无用例，只做提示
        this.$alert( '正在删除 '+ data.text +' 目录', '确认删除目录？', {
          dangerouslyUseHTMLString: true,
          confirmButtonText: '确认',
          type: 'info',
          center: true
        }).then(()=> {
          this.removeNode(node, data)
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        })
      }
    }
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val)
    }
  },
  mounted() {
    console.log( 'treeData: ',this.treeData);
    this.currentTree = this.treeData
  },
  computed: {
    scrollerHeight: function() {
      return (window.innerHeight - 250) + 'px';
    }
  }
}
</script>

<style lang="less" scoped>
.custom-tree-node-label {
  width: 130px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  display: block;
}
.grid-content {
  width: 320px;
  min-width: 250px;
  border-radius: 4px;
}
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
  position: relative;
}
/deep/ .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
  background-color: #9fcfec !important;
}
.custom-tree-node:hover .operate-btns{
  display: block;
}
.operate-btns {
  display: none;
  position: absolute;
  top: 50%;
  right: 5%;
  transform: translateY(-40%);
}
.custom-tree-node-wrapper {
  width: 100%;
}
</style>
